package org.shj.jvm.oom;

import java.util.ArrayList;
import java.util.List;


/**
 * VM args: -Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError
 * 
 * -XX:+HeapDumpOnOutOfMemoryError Add this argument to dump the error log when there is OutOfMemory exception
 *
 * 1 原因分析
 * 请求创建一个超大对象，通常是一个大数组
 * 超出预期的访问量/数据量，通常是上游系统请求流量飙升，常见于各类促销/秒杀活动，可以结合业务流量指标排查是否有尖状峰值
 * 过度使用终结器（Finalizer），该对象没有立即被 GC
 * 内存泄漏（Memory Leak），大量对象引用没有释放，JVM 无法对其自动回收，常见于使用了 File 等资源没有回收
 *
 * 2. 解决方案
 * 针对大部分情况，通常只需要通过 -Xmx 参数调高 JVM 堆内存空间即可。如果仍然没有解决，可以参考以下情况做进一步处理：
 *
 * 如果是超大对象，可以检查其合理性，比如是否一次性查询了数据库全部结果，而没有做结果数限制
 * 如果是业务峰值压力，可以考虑添加机器资源，或者做限流降级。
 * 如果是内存泄漏，需要找到持有的对象，修改代码设计，比如关闭没有释放的连接
 *
 * @author huangjian
 *
 */
public class HeapOOM {

	public static void main(String[] args) throws Exception{
		System.out.println("Hello Heap outof memory");
		List<Person> list = new ArrayList<Person>();
		int cnt = 0;
		while(true){
			list.add(new Person());
			//这段代码是为了便于用jconsole观察内存使用状况
			Thread.sleep(50);
			System.out.println(++cnt);
		}
	}
}

class Person{
	private byte[] big = new byte[1024*10];
}
